package org.melord.cap;

import org.dom4j.DocumentException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.wb.swt.SWTRes;
import org.melord.cap.ControlWraper.CountDownListener;

public class PopupDialog {

	private static final int MAX_CONTROL = 2;

	protected Object result;
	protected Shell parent;
	protected Shell shell;
	protected Label timeLabel;
	protected Host host;

	private String site = "";
	private long displayTime = 0;
	private long alertInterval = 0;
	private String alertSound;

	private ControlWraper[] urlControls;
	private StyleLabel[] timeLabels;
	private Font timeFont;

	private long currentTime;

	/**
	 * Create the dialog.
	 * 
	 * @param parent
	 * @param style
	 */
	public PopupDialog(Shell parent, Host host, long currentTime) {
		// super(parent, SWT.ON_TOP | SWT.NO_TRIM );
		// setText("警告");
		this.parent = parent;
		this.host = host;
		this.currentTime = currentTime;
		init();
	}

	private void init() {

		int count = host.getControls().size();
		count = count > MAX_CONTROL ? MAX_CONTROL : count;
		urlControls = new ControlWraper[count];
		for (int i = 0; i < count; i++) {
			urlControls[i] = new ControlWraper(host.getControls().get(i));
		}
		timeLabels = new StyleLabel[count];
	}

	public Shell getParent() {
		return parent;
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public Object open() {
		createContents();

		shell.setBackgroundImage(SWTRes.getImage(PopupDialog.class, "bg.gif"));

		shell.setBackgroundMode(SWT.INHERIT_FORCE);
		shell.open();
		shell.layout();

		startPopupAnimation();
		for (ControlWraper ctrl : urlControls) {
			// startCountDown(ctrl);
			// startAlert();
			ctrl.startCountDown(shell, new CountDownListener() {
				@Override
				public void update(ControlWraper ctrl, long remain) {

					String txt = formatTime(remain);// + "/" +
					// formatTime(countDown);

					getLabel(ctrl).setText(txt);
				}

				@Override
				public void stop(ControlWraper ctrl) {
					// TODO Auto-generated method stub

				}

			});
		}
		// startDismissAnimation();

		Display display = getParent().getDisplay();

		// while (!shell.isDisposed()) {
		// if (!display.readAndDispatch()) {
		// display.sleep();
		// }
		// }
		return result;
	}

	boolean over = false;
	Thread waitThread = new Thread() {
		public void run() {
			while (!over) {
				try {
					Thread.sleep(50);
					// getParent().getDisplay().readAndDispatch();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println(this.getId() + " dd stop");
		};
	};

	private StyleLabel getLabel(ControlWraper ctrl) {
		int idx = 0;
		for (int i = 0; i < urlControls.length; i++) {
			if (ctrl == urlControls[i]) {
				idx = i;
				break;
			}
		}
		return timeLabels[idx];
	}

	private void startDismissAnimation() {

		shell.getDisplay().timerExec((int) 0 * 1000, new Runnable() {
			@Override
			public void run() {
				if (shell.isDisposed()) {
					return;
				}
				shell.dispose();
				// shell.getParent().dispose();
			}
		});
	}

	private void startPopupAnimation() {
		final int time = 10;
		shell.getDisplay().timerExec(time, new Runnable() {

			@Override
			public void run() {
				if (shell.isDisposed()) {
					return;
				}
				int x = shell.getLocation().x;
				int y = shell.getLocation().y;

				int tempY = y - endY;
				int step = tempY < stepY ? tempY : stepY;
				// System.out.println("step: " + step);
				if (y > endY) {

					y = y - step;
					shell.setLocation(x, y);
					shell.getDisplay().timerExec(time, this);
				}
			}
		});
	}

	private GridData getGridData() {
		return new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		shell = new PopupShell(getParent().getDisplay(), SWT.ON_TOP
				| SWT.NO_TRIM);
		shell.setImage(shell.getDisplay().getSystemImage(SWT.ICON_WARNING));
		// shell.setText(getText());

		initPosAndSize();
		initFont();

		GridLayout gl_shell = new GridLayout(1, true);
		gl_shell.verticalSpacing = 0;
		gl_shell.marginWidth = 0;
		gl_shell.marginHeight = 0;
		gl_shell.horizontalSpacing = 0;
		shell.setLayout(gl_shell);

		Composite title = new Composite(shell, SWT.NONE);
		GridData gd_title = new GridData(SWT.FILL, SWT.CENTER, true, false, 1,
				1);
		gd_title.heightHint = 24;
		title.setLayoutData(gd_title);
		GridLayout gl_title = new GridLayout(2, false);
		gl_title.marginHeight = 0;
		gl_title.verticalSpacing = 0;
		title.setLayout(gl_title);

		MyCanvas canvas = new MyCanvas(title);
		canvas
				.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true, 1,
						1));
		canvas.init();

		Label icon = new Label(title, SWT.HORIZONTAL | SWT.CENTER);
		GridData gd_icon = new GridData(SWT.CENTER, SWT.CENTER, false, true, 1,
				1);
		icon.setLayoutData(gd_icon);
		// icon.setBackgroundImage(SWTRes.getImage(
		// PopupDialog.class, "/org/eclipse/wb/swt/warning.png"));
		// icon.setText(shell.getText());

		createSubContents(shell);

		Composite composite = new Composite(shell, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		GridLayout gl_composite = new GridLayout(1, false);
		gl_composite.marginHeight = 0;
		composite.setLayout(gl_composite);

		Button btn = new Button(composite, SWT.CENTER);
		GridData gd_btn = new GridData(SWT.CENTER, SWT.CENTER, true, false, 1,
				1);
		gd_btn.widthHint = 100;
		btn.setLayoutData(gd_btn);
		btn.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				MessageBox box = new MessageBox(shell, SWT.ICON_QUESTION
						| SWT.OK | SWT.CANCEL);
				box.setMessage("确认结束当前任务?");
				box.setText("温馨提示");

				int code = box.open();
				if (code == SWT.OK) {
					System.out.println("user close popup");
					result = SWT.CLOSE;
					// OS.EnableWindow(shell.handle, false);
					rePos();
					for (ControlWraper ctrl : urlControls) {
						ctrl.stop(shell);
					}
					shell.close();

					if (listener != null) {
						listener.onClose(host);
					}
				}
			}
		});
		// btn.setLayoutData(getGridData());
		btn.setText("任务完成");
	}

	private void initFont() {
		Font initialFont = shell.getFont();
		FontData[] fontData = initialFont.getFontData();
		for (int i = 0; i < fontData.length; i++) {
			fontData[i].setHeight(20);
		}
		timeFont = new Font(shell.getDisplay(), fontData);

	}

	private void createSubContents(Composite parent) {
		ScrolledComposite scrolledComposite = new ScrolledComposite(parent,
				SWT.V_SCROLL);
		GridData gd_scrolledComposite = new GridData(SWT.FILL, SWT.FILL, true,
				true, 1, 1);
		gd_scrolledComposite.heightHint = 160;
		scrolledComposite.setLayoutData(gd_scrolledComposite);
		scrolledComposite.setExpandVertical(true);
		scrolledComposite.setExpandHorizontal(true);
		Composite comp = new Composite(scrolledComposite, SWT.NONE);
		comp.setLayout(new GridLayout(1, false));

		for (int i = 0; i < timeLabels.length; i++) {
			StyleLabel label = newTextLabel(comp);
			label.setText(urlControls[i].getText());
			label.enableStyle(urlControls[i]);
			// label.setLayoutData(getGridData());

			StyleLabel lbl = newTimeLabel(comp);
			lbl.setText(formatTime(urlControls[i].getTime()));
			// lbl.setLayoutData(getGridData());
			timeLabels[i] = lbl;
		}

		StyleLabel desc = newTextLabel(comp);
		desc.setText(host.getRemindText());
		desc.setLayoutData(getGridData());

		for (int i = 0; i < host.getReminds().size(); i++) {
			Label label = newNormalLabel(comp);
			label.setText(host.getReminds().get(i));
			// label.setLayoutData(getGridData());
		}

		scrolledComposite.setContent(comp);
		scrolledComposite
				.setMinSize(comp.computeSize(SWT.DEFAULT, SWT.DEFAULT));

	}

	private void initPosAndSize() {
		shell.setSize(childShellWidth, childShellHeight);
		Rectangle screen = Display.getDefault().getClientArea();
		startX = screen.width - childShellWidth - 1;
		startY = computeStartY();// screen.height - 1;
		endY = startY - childShellHeight;

		shell.setLocation(startX, startY);

	}

	private int computeStartY() {
		Shell[] shells = shell.getDisplay().getShells();
		int popupNum = -1;
		if (shells != null) {
			for (Shell s : shells) {
				if (s instanceof PopupShell) {
					popupNum++;
				}
			}
		}
		System.out.println("popups:" + popupNum);
		return Display.getDefault().getClientArea().height - 1
				- verticalSpacing * popupNum;
	}

	private void rePos() {
		Shell[] shells = shell.getDisplay().getShells();
		boolean find = false;
		if (shells != null) {
			for (final Shell s : shells) {
				if (s instanceof PopupShell && !s.isDisposed()) {
					if (!s.isDisposed() && find) {
						shells[shells.length - 1].getDisplay().asyncExec(
								new Runnable() {

									@Override
									public void run() {
										s.setLocation(s.getLocation().x, s
												.getLocation().y
												+ verticalSpacing);
									}
								});

					}
					if (s == shell) {
						find = true;
					}
				}
			}
		}
	}

	int childShellHeight = 240;
	int childShellWidth = 292;

	int startX = 0;
	int startY = 0;
	int endX = 0;
	int endY = 0;
	int stepX = 15;
	int stepY = 15;
	int verticalSpacing = childShellHeight;
	int horizontalSpacing = 0;

	public static String formatTime(long time) {
		int t = (int) (time / 1000);
		int h = t / 3600;
		int m = (t % 3600) / 60;
		int s = (t % 3600) % 60;
		return String.format("%02d:%02d:%02d", h, m, s);
	}

	public interface PopupListener {
		void onClose(Host host);
	}

	PopupListener listener;

	public void setPopupListener(PopupListener listener) {
		this.listener = listener;
	}

	public static void main(String[] args) {
		Display display = new Display();
		final Shell shell = new Shell(display);
		// shell.open();
		HostsManager mgr = new HostsManager();
		try {
			mgr.parse("hosts.xml");
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		final Host host = mgr.getHosts().get(0);
		System.out.println(host);
		Thread t = new Thread() {
			@Override
			public void run() {
				new PopupDialog(shell, host, System.currentTimeMillis()).open();

				System.out.println("t stop");
			}
		};

		Thread t2 = new Thread() {
			@Override
			public void run() {
				new PopupDialog(shell, host, System.currentTimeMillis()).open();
				System.out.println("t2 stop");
			}
		};
		// t.start();t2.start();
		display.asyncExec(t);
		display.asyncExec(t2);
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		System.out.println("over");
		display.dispose();
	}

	private final StyleLabel newTimeLabel(Composite parent) {
		StyleLabel lbl = new StyleLabel(parent);
		lbl.setForeground(SWTRes.getColor(SWT.COLOR_RED));
		lbl.setFont(SWTRes.getBoldFont(timeFont));
		lbl.setLayoutData(getGridData());
		return lbl;
	}

	private final StyleLabel newTextLabel(Composite parent) {
		StyleLabel lbl = new StyleLabel(parent);
		// lbl.setForeground(SWTRes.getColor(SWT.COLOR_BLUE));
		// lbl.setFont(SWTRes.getBoldFont(shell.getFont()));
		lbl.setLayoutData(getGridData());
		return lbl;
	}

	private final Label newNormalLabel(Composite parent) {
		Label lbl = new Label(parent, SWT.CENTER);
		// lbl.setForeground(SWTRes.getColor(SWT.COLOR_BLUE));
		// lbl.setFont(SWTRes.getBoldFont(shell.getFont()));
		lbl.setLayoutData(getGridData());
		return lbl;
	}
}

class MyCanvas extends Canvas implements PaintListener {
	final Image image;

	public MyCanvas(Composite parent) {
		super(parent, SWT.NONE);
		image = parent.getDisplay().getSystemImage(SWT.ICON_WARNING);
	}

	public void init() {
		// Region region = new Region();
		// Rectangle pixel = new Rectangle(0, 0, 1, 1);
		// for (int y = 0; y < 32; y += 1) {
		// for (int x = 0; x < 32; x += 1) {
		// pixel.x = x;
		// pixel.y = y;
		// region.add(pixel);
		// }
		// }
		// // define the shape of the shell using setRegion
		// setRegion(region);
		// Rectangle size = region.getBounds();
		// setSize(size.width, size.height);
		addPaintListener(this);
	}

	@Override
	public void paintControl(PaintEvent e) {
		Rectangle bounds = image.getBounds();
		Point size = getSize();
		e.gc.drawImage(image, 0, 0, bounds.width, bounds.height, 0, 0, 24, 24);
	}

}